package coroutines

import kotlinx.coroutines.*
import java.lang.ArithmeticException
import java.lang.Exception
import kotlin.system.measureTimeMillis

suspend fun doSomethingOne(): Int{
    delay(1000L)
    return 13
}

suspend fun doSomethingTwo(): Int{
    delay(1000L)
    return 29
}

fun main(){
    /*runBlocking {

        measureTimeMillis {
            val one = doSomethingOne()
            val two = doSomethingTwo()
            println("The answer is ${one + two}")
        }
    }*/

    /*runBlocking {
        val one = async { doSomethingOne() }
        val two = async { doSomethingTwo() }
        println("minus = ${two.await() - one.await()}")
    }
    runBlocking {
        val one = async(start = CoroutineStart.LAZY) { doSomethingOne() }
        val two = async(start = CoroutineStart.LAZY) { doSomethingTwo() }
        println("sum = ${one.await() - two.await()}")
    }*/
    runBlocking {
        try {
            failedConcurrentSUm()
        }catch (e : Exception){
            println("Computation failed with ArithmeticException")
        }
    }
}

suspend fun failedConcurrentSUm() : Int = coroutineScope {
    val one = async<Int> {
        try {
            delay(Long.MAX_VALUE)
            42
        }finally {
            println("First child was cancelled")
        }
    }
    val two = async<Int> {
        println("Second child thorws an exception")
        throw ArithmeticException()
    }
    one.await() + two .await()
}